package com.magicodex.bookkeeping.biz.accounting.util;

import com.magicodex.bookkeeping.biz.accounting.dto.AccountingDTO;
import com.magicodex.bookkeeping.biz.common.constant.CollectionConstants;
import com.magicodex.bookkeeping.biz.common.exception.ApplicationException;
import com.magicodex.bookkeeping.biz.common.util.CollectionUtil;
import com.magicodex.bookkeeping.biz.common.util.DateUtil;
import com.magicodex.bookkeeping.biz.common.util.NumberUtil;
import com.magicodex.bookkeeping.biz.common.util.StringUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author mh.z
 */
public class AccountingJsonUtil {
    private static final String FIELD_ACCOUNT = "account";
    private static final String FIELD_MONEY = "money";
    private static final String FIELD_LAST_CHECKED_DATE = "lastCheckedDate";

    /**
     * 序列化成字符串
     *
     * @param records
     * @return
     */
    public static String stringifyAccountingDTOs(List<AccountingDTO> records) {
        if (CollectionUtil.isEmpty(records)) {
            return "{}";
        }

        JSONArray jsonArray = new JSONArray();

        for (int index = 0; index < records.size(); index++) {
            AccountingDTO record = records.get(index);
            JSONObject jsonObject = new JSONObject();

            try {
                // 账户
                String account = record.getAccount();
                jsonObject.put(FIELD_ACCOUNT, StringUtil.orEmpty(account));

                // 金额
                BigDecimal money = record.getMoney();
                String moneyStr = NumberUtil.formatNumber(money);
                jsonObject.put(FIELD_MONEY, StringUtil.orEmpty(moneyStr));

                // 最后核对日期
                ZonedDateTime date = record.getLastCheckedDate();
                String dateStr = DateUtil.formatYearSecond(date);
                jsonObject.put(FIELD_LAST_CHECKED_DATE, StringUtil.orEmpty(dateStr));
            } catch (JSONException e) {
                throw new ApplicationException(e);
            }

            jsonArray.put(jsonObject);
        }

        return jsonArray.toString();
    }

    /**
     * 解析字符串
     *
     * @param text
     * @return
     */
    public static List<AccountingDTO> parseAccountingDTOs(String text) {
        if (StringUtil.isEmpty(text)) {
            return Collections.emptyList();
        }

        List<AccountingDTO> recordList = new ArrayList<>(CollectionConstants.DEFAULT_LIST_INITIAL_CAPACITY);

        try {
            JSONArray jsonArray = new JSONArray(text);

            for (int index = 0; index < jsonArray.length(); index++) {
                JSONObject jsonObject = jsonArray.getJSONObject(index);
                AccountingDTO record = new AccountingDTO();

                // 账户
                String account = jsonObject.optString(FIELD_ACCOUNT);
                record.setAccount(account);

                // 金额
                String moneyStr = jsonObject.optString(FIELD_MONEY);
                BigDecimal money = NumberUtil.parseNumber(moneyStr);
                record.setMoney(money);

                // 最后核对日期
                String dateStr = jsonObject.optString(FIELD_LAST_CHECKED_DATE);
                ZonedDateTime date = DateUtil.parseYearSecond(dateStr);
                record.setLastCheckedDate(date);

                recordList.add(record);
            }
        } catch (JSONException e) {
            throw new ApplicationException(e);
        }

        return recordList;
    }

}
